package fr.utbm.gi.in56.ads;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.sun.net.httpserver.HttpPrincipal;

import fr.utbm.gi.in56.database.ConnectionPool;
import fr.utbm.gi.in56.database.ConnectionServlet;
import fr.utbm.gi.in56.database.DatabaseServlet;
import fr.utbm.gi.in56.error.ErrorType;
import fr.utbm.gi.in56.notification.NotificationType;
import fr.utbm.gi.in56.user.UserBean;

/**
 * Servlet to post a buy ad
 *
 * @author Adrien Hoffer & Tarik Belabbas
 *
 */
@WebServlet("/PostBuyAdServlet")
public class PostBuyAdServlet extends AdServlet
{

	/**
	 * Version number associated to the serializable class.
	 */
	private static final long	serialVersionUID	= 2088669793456384977L;
	
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	
	public PostBuyAdServlet()
	{
		super();
	}
	
	@Override
	protected void doPost( HttpServletRequest request,
			HttpServletResponse response ) throws ServletException, IOException
	{
		request.setCharacterEncoding( "UTF-8" ); //$NON-NLS-1$
		
		String title = request.getParameter( "title" ); //$NON-NLS-1$
		int idBrand 		= Integer.parseInt( request.getParameter( "brand" ) ); //$NON-NLS-1$
		int idModel 		= ( request.getParameter( "model" ) == null ) ? 0 :  //$NON-NLS-1$
			Integer.parseInt( request.getParameter( "model" ) ); //$NON-NLS-1$
		int vehicleYearMin 	= Integer.parseInt( request.getParameter( "vehicle_year_min" ) ); //$NON-NLS-1$
		int vehicleYearMax 	= Integer.parseInt( request.getParameter( "vehicle_year_max" ) ); //$NON-NLS-1$
		
		int idEnergy 		= Integer.parseInt( request.getParameter( "energy" ) ); //$NON-NLS-1$
		int automatic 		= Integer.parseInt( request.getParameter( "is_automatic" ) ); //$NON-NLS-1$
		String description 	= request.getParameter( "description" ); //$NON-NLS-1$
		
		int[] kmNbMin = new int[1];
		int[] kmNbMax = new int[1];
		int[] priceMin = new int[1];
		int[] priceMax = new int[1];
		
		// Get a representative value for the minimum number of kilometers
		if( ! handleParameter( request, "km_nb_min", kmNbMin, response, ErrorType.FIELD_NAN ) ) //$NON-NLS-1$
		{
			return;
		}

		// Get a representative value for the maximum number of kilometers
		if( ! handleParameter( request, "km_nb_max", kmNbMax, response, ErrorType.FIELD_NAN ) ) //$NON-NLS-1$
		{
			return;
		}
	
		// Get a representative value for the minimum price
		if( ! handleParameter( request, "price_min", priceMin, response, ErrorType.FIELD_NAN ) ) //$NON-NLS-1$
		{
			return;
		}
		
		// Get a representative value for the minimum price
		if( ! handleParameter( request, "price_max", priceMax, response, ErrorType.FIELD_NAN ) ) //$NON-NLS-1$
		{
			return;
		}
		
		// Test if the title is empty
		if( title.isEmpty() )
		{
			returnError( request, response, ErrorType.EDIT_TITLE_EMPTY );
			return;
		}
		
		// Test the chronology between dates
		if( vehicleYearMax != 0 && vehicleYearMin != 0 && vehicleYearMax < vehicleYearMin )
		{
			returnError( request, response, ErrorType.EDIT_VEHICLE_DATE );
			return;
		}
		
		if( kmNbMax[0] != -1 && kmNbMin[0] != -1 && kmNbMax[0] < kmNbMin[0] )
		{
			returnError( request, response, ErrorType.EDIT_VEHICLE_KMS );
			return;
		}
		
		if( priceMax[0] != -1 && priceMin[0] != -1 &&	priceMax[0] < priceMin[0] )
		{
			returnError( request, response, ErrorType.EDIT_VEHICLE_PRICE );
			return;
		}
		
		AdsManager adsBuyMg = new AdsManager( getConnection() );
		
		// Get the current user
		HttpSession session = request.getSession( true );
		UserBean user = (UserBean)session.getAttribute( "currentSessionUser" ); //$NON-NLS-1$
		
		int createdId = adsBuyMg.postBuyAd( title, idBrand, idModel,
				vehicleYearMin, vehicleYearMax, kmNbMin[0], kmNbMax[0],
				priceMin[0], priceMax[0], idEnergy, automatic,
				description, user.getLogin() );
		
		if(  createdId == -1 )
		{
			returnError( request, response, ErrorType.DB_ERROR );
			return;
		}
		
		ServletContext context	= getServletContext();
		String key				= ConnectionServlet.getPoolKey();
		Object object			= context.getAttribute( key );
		
		AdBuy adbuy = adsBuyMg.getAdBuy( createdId );
		BuyAdMatcher bsm = new BuyAdMatcher( adbuy, (ConnectionPool)object, user.getLogin() );
		bsm.run();
		
		request.setAttribute( "notification", NotificationType.AD_SUBMITTED ); //$NON-NLS-1$
		RequestDispatcher rd = request.getRequestDispatcher("notification.jsp"); //$NON-NLS-1$
		rd.forward( request, response );
		return;
	}
	
	/**
	 * Sets the error as request attribute and forward to previous page.
	 * 
	 * @param _error the error
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void returnError( HttpServletRequest request,
			HttpServletResponse response, ErrorType _error ) throws ServletException, IOException
	{
		ErrorType result = forwardEnergyAndCarLists( request, response );
		if ( result != ErrorType.NONE )
		{
			request.setAttribute( "error", result ); //$NON-NLS-1$
			RequestDispatcher rd = request.getRequestDispatcher("error.jsp"); //$NON-NLS-1$
			rd.forward( request, response );
		}
		else
		{
			request.setAttribute( "postAdError", _error ); //$NON-NLS-1$
			RequestDispatcher rd = request.getRequestDispatcher("postBuyAd.jsp"); //$NON-NLS-1$
			rd.forward( request, response );
		}
	}
	
	/**
	 * Sets the parameter to -1 if the parameter value is null,
	 * to the corresponding integer value if there is no format problem.
	 * 
	 * @param _request the servlet request
	 * @param _parameter the parameter to check
	 * @param _parameterValue the parameter to initialize
	 * @param _response the servlet response
	 * @param _errorToReturn the error to return
	 * @return <tt>true</tt> if there is no format exception
	 * @throws ServletException
	 * @throws IOException
	 */
	private boolean handleParameter( HttpServletRequest _request, String _parameter,
			int[] _parameterValue, HttpServletResponse _response, ErrorType _errorToReturn ) throws ServletException, IOException
	{
		if( _request.getParameter( _parameter ).isEmpty())
		{
			_parameterValue[0] = -1;
			return true;
		}
		try
		{
			_parameterValue[0] = Integer.parseInt( _request.getParameter( _parameter ) );
			if( _parameterValue[0] < 0 )
			{
				returnError( _request, _response, _errorToReturn );
				return false;
			}
			return true;
		}
		catch (NumberFormatException e)
		{
			returnError( _request, _response, _errorToReturn );
			return false;
		}
	}
}
